generator client {
  provider      = "prisma-client-js"
  binaryTargets = ["native", "linux-musl-openssl-3.0.x"]
}

datasource db {
  provider = "mongodb"
  url      = env("MONGOHQ_URL")
}

// USER COLLECTION ---------------------

type File {
  contents String
  ext      String
  key      String
  name     String
  path     String? // Undefined | Null
}

type CompletedChallenge {
  challengeType      Int?         @db.Int // Null | Undefined
  completedDate      Float // TODO(Post-MVP): Change to DateTime
  files              File[]
  githubLink         String? // Undefined
  id                 String
  isManuallyApproved Boolean? // Undefined
  solution           String? // Null | Undefined
  examResults        ExamResults? // Undefined
}

type PartiallyCompletedChallenge {
  id            String
  completedDate Float
}

type Portfolio {
  description String
  id          String
  image       String
  title       String
  url         String
}

type ProfileUI {
  isLocked      Boolean? // Undefined
  showAbout     Boolean? // Undefined
  showCerts     Boolean? // Undefined
  showDonation  Boolean? // Undefined
  showHeatMap   Boolean? // Undefined
  showLocation  Boolean? // Undefined
  showName      Boolean? // Undefined
  showPoints    Boolean? // Undefined
  showPortfolio Boolean? // Undefined
  showTimeLine  Boolean? // Undefined
}

// Currently unused, so commented out.
// type ProgressTimestamp {
//   timestamp Float
// }

type SavedChallengeFile {
  contents String
  ext      String
  history  String[]
  key      String
  name     String
}

type SavedChallenge {
  files         SavedChallengeFile[]
  id            String
  lastSavedDate Float
}

model user {
  id                           String                        @id @default(auto()) @map("_id") @db.ObjectId
  about                        String
  acceptedPrivacyTerms         Boolean
  // badges    Json? // Undefined | { coreTeam [][] } removed, as new API never uses it.
  completedChallenges          CompletedChallenge[]
  completedExams               CompletedExam[] // Undefined
  currentChallengeId           String?
  donationEmails               String[] // Undefined | String[] (only possible for built in Types like String)
  email                        String
  emailAuthLinkTTL             DateTime? // Null | Undefined
  emailVerified                Boolean
  emailVerifyTTL               DateTime? // Null | Undefined
  externalId                   String
  // github    String? Removed, because value was only ever found to be Null
  githubProfile                String? // Undefined
  isApisMicroservicesCert      Boolean? // Undefined
  isBackEndCert                Boolean? // Undefined
  isBanned                     Boolean? // Undefined
  isCheater                    Boolean? // Undefined
  isDataAnalysisPyCertV7       Boolean? // Undefined
  isDataVisCert                Boolean? // Undefined
  isDonating                   Boolean
  isFoundationalCSharpCertV8   Boolean? // Undefined
  isFrontEndCert               Boolean? // Undefined
  isFrontEndLibsCert           Boolean? // Undefined
  isFullStackCert              Boolean? // Undefined
  isHonest                     Boolean?
  isInfosecCertV7              Boolean? // Undefined
  isInfosecQaCert              Boolean? // Undefined
  isJsAlgoDataStructCert       Boolean? // Undefined
  isJsAlgoDataStructCertV8     Boolean? // Undefined
  isMachineLearningPyCertV7    Boolean? // Undefined
  isQaCertV7                   Boolean? // Undefined
  isRelationalDatabaseCertV8   Boolean? // Undefined
  isRespWebDesignCert          Boolean? // Undefined
  isSciCompPyCertV7            Boolean? // Undefined
  is2018DataVisCert            Boolean? // Undefined
  is2018FullStackCert          Boolean? // Undefined
  isCollegeAlgebraPyCertV8     Boolean? // Undefined
  isUpcomingPythonCertV8       Boolean? // Undefined
  keyboardShortcuts            Boolean? // Undefined
  linkedin                     String? // Null | Undefined
  location                     String? // Null
  name                         String? // Null
  needsModeration              Boolean? // Undefined
  newEmail                     String? // Null | Undefined
  partiallyCompletedChallenges PartiallyCompletedChallenge[] // Undefined | PartiallyCompletedChallenge[]
  password                     String? // Undefined
  picture                      String
  portfolio                    Portfolio[]
  profileUI                    ProfileUI? // Undefined
  progressTimestamps           Json? // ProgressTimestamp[] | Null[] | Int64[] | Double[] - TODO: NORMALIZE
  // rand Float? // Undefined removed, as new API never uses it.
  savedChallenges              SavedChallenge[] // Undefined | SavedChallenge[]
  sendQuincyEmail              Boolean
  theme                        String? // Undefined
  timezone                     String? // Undefined
  twitter                      String? // Null | Undefined
  unsubscribeId                String
  username                     String // TODO(Post-MVP): make this unique
  usernameDisplay              String? // Undefined
  verificationToken            String? // Undefined
  website                      String? // Undefined
  yearsTopContributor          String[] // Undefined | String[]
  isClassroomAccount           Boolean? // Undefined
}

// -----------------------------------

model AccessToken {
  id      String   @id @map("_id")
  created DateTime @db.Date
  ttl     Int
  userId  String   @db.ObjectId

  @@index([userId], map: "userId_1")
}

model AuthToken {
  id      String   @id @map("_id")
  created DateTime @db.Date
  ttl     Int
  userId  String   @db.ObjectId
}

model Donation {
  id             String            @id @default(auto()) @map("_id") @db.ObjectId
  amount         Int               @db.Int
  customerId     String
  duration       String?
  email          String
  endDate        DonationEndDate?
  provider       String
  startDate      DonationStartDate
  subscriptionId String
  userId         String            @db.ObjectId

  @@index([email], map: "email_1")
  @@index([userId], map: "userId_1")
}

model UserRateLimit {
  id             String @id @default(auto()) @map("_id") @db.ObjectId
  /// Field referred in an index, but found no data to define the type.
  expirationDate Json?

  @@index([expirationDate], map: "expirationDate_1")
}

model UserToken {
  id      String   @id @map("_id")
  created DateTime @db.Date
  ttl     Float
  userId  String   @db.ObjectId

  @@index([userId], map: "userId_1")
}

model sessions {
  id      String   @id @map("_id")
  expires DateTime @db.Date
  session String

  @@index([expires], map: "expires_1")
}

model MsUsername {
  id         String @id @default(auto()) @map("_id") @db.ObjectId
  userId     String @db.ObjectId
  ttl        Int
  msUsername String

  @@index([userId, id], map: "userId_1__id_1")
  @@index([msUsername], map: "msUsername_1")
}

model Exam {
  id                      String         @id @map("_id") @db.ObjectId
  numberOfQuestionsInExam Int            @db.Int
  passingPercent          Int            @db.Int
  prerequisites           Prerequisite[] // undefined | Prerequisite[]
  title                   String
  questions               Question[]
}

type CompletedExam {
  id            String
  challengeType Int
  completedDate Float // TODO(Post-MVP): Change to DateTime?
  examResults   ExamResults
}

type ExamResults {
  numberOfCorrectAnswers  Int
  numberOfQuestionsInExam Int
  percentCorrect          Float
  passingPercent          Int
  passed                  Boolean
  examTimeInSeconds       Int
}

type Question {
  id             String
  question       String
  wrongAnswers   Answer[]
  correctAnswers Answer[]
  deprecated     Boolean? // undefined
}

type Answer {
  id         String
  answer     String
  deprecated Boolean? // undefined
}

type Prerequisite {
  id    String @db.ObjectId
  title String
}

type DonationEndDate {
  date DateTime @map("_date") @db.Date
  when String   @map("_when")
}

type DonationStartDate {
  date DateTime @map("_date") @db.Date
  when String   @map("_when")
}

model Survey {
  id        String           @id @default(auto()) @map("_id") @db.ObjectId
  userId    String           @db.ObjectId
  title     String
  responses SurveyResponse[]

  @@index([userId], map: "userId_1")
}

type SurveyResponse {
  question String
  response String
}
